/*
 * @file            include/connection_pool.h
 * @description     
 * @author          diabio <2591674331@qq.com>
 * @createTime      2025-05-06 20:43:04
 * @lastModified    2025-05-18 22:51:16
 * Copyright ©diabio All rights reserved
*/

#ifndef CONNECTION_POOL_H 
#define CONNECTION_POOL_H
#include <mysql/mysql.h>
#include <mysql/mysql_com.h>
#include <pthread.h>
#include <time.h>

// 魔法数字
#define DEFAULT_GET_CONN_TIMEOUT_MS 1000  // 默认获取连接超时1秒
#define IDLE_CONN_CLEANUP_SEC 300         // 空闲连接清理间隔5分钟
#define ERROR_MSG_MAX_LEN 256             // 错误信息最大长度


// 自定义连接池错误码 (使用负数以区分系统/pthread错误码)
#define CP_SUCCESS                             0  // 操作成功

#define CP_ERR_UNKNOWN                        -1  // 未知或未指定的错误
#define CP_ERR_MALLOC                         -2  // 内存分配失败
#define CP_ERR_INIT_POOL_FAILED               -3  // 连接池初始化失败 (例如，初始连接创建失败)
#define CP_ERR_GET_TIME_FAILED                -4  // 获取系统时间失败 (例如，用于超时计算)
#define CP_ERR_CONN_NOT_IN_POOL               -5  // 指定的连接不在此连接池中
#define CP_ERR_DESTROY_INCOMPLETE             -6  // 连接池销毁不完整或失败
#define CP_ERR_MYSQL_INIT_FAILED              -10 // mysql_init() 失败
#define CP_ERR_MYSQL_CONNECT_FAILED           -11 // MySQL连接失败 (通常也会用 mysql_errno 获取更具体的信息)
#define CP_ERR_POOL_FULL                      -12 // 池子满了（在我们创建连接的期间被其他线程填满）
#define CP_ERR_INTERNAL                       -13 // 这表示连接池内部状态不一致
#define CP_ERR_CONN_INVALID_STRUCT            -14 // 这表示非法的Connection_t结构,一般是NULL
// 注意: mysql_real_connect() 失败时，具体的MySQL错误码会存储在 Connection_t->error.errorCode 中
//       连接池的 lastError.errorCode 可能会设为更通用的错误，如 CP_ERR_INIT_POOL_FAILED

// 超时配置结构体
typedef struct TimeoutConfig_s {
    int timeoutMs;         // 获取连接的超时时间，单位：毫秒
} TimeoutConfig_t;

// 错误信息结构体
typedef struct ErrorInfo_s {
    int errorCode;         // 错误码
    char errorMsg[ERROR_MSG_MAX_LEN];    // 错误信息
} ErrorInfo_t;

typedef struct Connection_s{
    MYSQL *conn;           // mysql连接对象 
    int isFree;            // 是否正在使用
    time_t createTime;     // 创建时间
    time_t lastUsedTime;   // 最后使用时间
    ErrorInfo_t error;     // 连接错误信息
}Connection_t;

// 数据库配置信息
typedef struct DataBase_s{
    const char *host;
    int port;
    const char *user;
    const char *password;
    const char *dbName;
}DataBase_t;

// 连接池
typedef struct ConnectionPool_s{
    Connection_t* connlist;    // 连接池
    int connPoolSize;          // 连接池大小
    int initConnNum;           // 初始连接数
    int curConnNum;            // 当前连接数
    int freeConnNum;           // 空闲连接数
    pthread_mutex_t mutex;     // 互斥锁
    pthread_cond_t cond;       // 然线程等待的条件变量
    DataBase_t db;             // 数据库配置信息
    TimeoutConfig_t timeout;   // 超时配置信息
    ErrorInfo_t lastError;     // 连接池最后一次错误信息
}ConnectionPool_t;

ConnectionPool_t *createConnectionPool(DataBase_t db, int connStartNum, int connPoolSize);      // 创建连接池
Connection_t* getConnection(ConnectionPool_t *connPool);                                        // 获取连接
int releaseConnection(ConnectionPool_t* connPool, Connection_t* conn);                          // 释放连接
int destroyConnectionPool(ConnectionPool_t *connPool);                                          // 销毁连接池
void poolCleanup(ConnectionPool_t* connPool);                                                  // 连接池清理函数
int checkConnectionHealth(Connection_t *conn);                                                  // 连接健康检查
#endif